package busterminal.menu;

import busterminal.command.AbstractCommand;
import busterminal.exception.BusinessException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * Класс для работы с меню
 */
public class Menu extends AbstractCommand {

    /**
     * Коллекция, содержащая информацию о всех командах
     */
    private Map<Integer, AbstractCommand> commands = new HashMap<Integer, AbstractCommand>();
    /**
     * Номер пункта меню
     */
    private int counter = 0;
    /**
     * Объект "сканер" для ввода из консоли
     * Считывается параметр "consoleEncoding" из командной строки
     * -DconsoleEncoding=Cp1251
     */
    private Scanner scanner = new Scanner(System.in, System.getProperty("consoleEncoding") != null ? System.getProperty("consoleEncoding") : Charset.defaultCharset().name());

    /**
     * Параметризированный конструктор
     * @param menuName имя команды
     */
    public Menu(String menuName) {
        super(menuName);
    }

    /**
     * Выполнить команду
     */
    @Override
    public void execute() {
        System.out.println("--- Menu ---");
        for (Map.Entry<Integer, AbstractCommand> entry : commands.entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue().getName());
        }
        System.out.println("  Enter item number:");

        int item;
        String line = scanner.nextLine();
        try {
            item = Integer.parseInt(line);
        } catch (Exception e) {
            System.err.println("Incorrect item number='" + line + "'; " + e.toString());
            return;
        }

        AbstractCommand command = commands.get(item);
        if (command == null) {
            System.err.println("Incorrect item number='" + line + "'");
            return;
        }

        if (!command.getParametersNames().isEmpty()) {
            System.out.println("Enter params value");
            for (String parameterName : command.getParametersNames()) {
                System.out.println("Enter " + parameterName);
                command.showAccessableVariants(parameterName);
                String paramValue = scanner.nextLine();
                command.setParameter(parameterName, paramValue);
            }
        }

        try {
            command.execute();
        } catch (BusinessException e) {
            System.err.println("Exception while command execution: " + e.getMessage());
            if (e.getCause() != null) {
                System.err.println("Details:");
                e.getCause().printStackTrace(System.err);
            } else {
                System.err.println("Details are absent");
            }
        }
    }

    /**
     * Добавить команду
     * @param command команда
     */
    public void addCommand(AbstractCommand command) {
        commands.put(++counter, command);
    }
}
